/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package roshambo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static roshambo.Player.PAPEL;
import static roshambo.Player.PEDRA;
import static roshambo.Player.TESOURA;

/**
 *
 * @author ilima
 */
public class Roshambo {

    private final List<Player> players;

    public Roshambo() {
        players = new ArrayList<>();
    }

    private static int p1Payoff(int p1, int p2) throws Exception {
        if (p1 == p2) {
            return 0;
        }

        if (p1 == PEDRA) {
            if (p2 == PAPEL) {
                return -1;
            } else {
                return 1;
            }
        }

        if (p1 == PAPEL) {
            if (p2 == TESOURA) {
                return -1;
            } else {
                return 1;
            }
        }

        if (p1 == TESOURA) {
            if (p2 == PEDRA) {
                return -1;
            } else {
                return 1;
            }
        }

        throw new Exception("Only {1,2,3} values are allowed to be played. Received {" + p1 + ", " + p2 + "}");
    }

    public void addPlayer(Player p) {
        this.players.add(p);
    }

    public void removePlayer(Player p) {
        this.players.remove(p);
    }

    public List<Player> getPlayers() {
        return players;
    }

    /**
     * @param games the command line arguments
     * @throws java.lang.Exception
     */
    public void start(int games) throws Exception {
        int[] wins = new int[players.size()];
        int[] winner = new int[players.size()];
        float[] totalTimes = new float[players.size()];
        int p1p, play1, play2;

        for (int i = 0; i < players.size(); i++) {
            wins[i] = 0;
            winner[i] = 0;
            totalTimes[i] = 0;
        }
        for (int i = 0; i < players.size(); i++) {
            for (int j = i + 1; j < players.size(); j++) {
                Player p1 = players.get(i);
                Player p2 = players.get(j);

                long start1 = System.currentTimeMillis();
                p1.newGame(games);
                long endTime1 = System.currentTimeMillis() - start1;
                totalTimes[i] += endTime1;

                long start2 = System.currentTimeMillis();
                p2.newGame(games);
                long endTime2 = System.currentTimeMillis() - start2;
                totalTimes[j] += endTime2;

                int wins1 = 0, wins2 = 0;

                for (int k = 0; k < games; k++) {

                    start1 = System.currentTimeMillis();
                    play1 = p1.play();
                    endTime1 = System.currentTimeMillis() - start1;
                    totalTimes[i] += endTime1;

                    start2 = System.currentTimeMillis();
                    play2 = p2.play();
                    endTime2 = System.currentTimeMillis() - start2;
                    totalTimes[j] += endTime2;

                    p1p = p1Payoff(play1, play2);
                    wins[i] += p1p;
                    wins[j] += -p1p;
                    wins1 += p1p;
                    wins2 += -p1p;

                    start1 = System.currentTimeMillis();
                    p1.receive(play2);
                    endTime1 = System.currentTimeMillis() - start1;
                    totalTimes[i] += endTime1;

                    start2 = System.currentTimeMillis();
                    p2.receive(play1);
                    endTime2 = System.currentTimeMillis() - start2;
                    totalTimes[j] += endTime2;
//                    System.out.println("[i,j):k " + i + "," + j + ":" + k + " "
                    //                            + " " + p1.getClass().getName() + " " + getName(play1)
                    //                            + " " + p2.getClass().getName() + " " + getName(play2));
                }
                System.out.println(" (" + wins1 + " x " + wins2 + ") [" + totalTimes[i] / 1000F + "s x " + totalTimes[j] / 1000F + "s] "
                        + p1.getClass().getName() + " x " + p2.getClass().getName()
                );
                if (wins1 == wins2) {
                    winner[i] += 1;
                }
                if (wins1 > wins2) {
                    winner[i] += 3;
                } else {
                    winner[j] += 3;
                }
            }
        }
        List<Score> scores = new ArrayList<Score>();
        for (int i = 0; i < wins.length; i++) {
            scores.add(new Score(players.get(i).getClass().getName(), winner[i], wins[i], totalTimes[i]));
        }
        Collections.sort(scores);
        for (Score s : scores) {
            System.out.println(s);
        }
//        System.out.println(Arrays.toString(winner));;
    }

    private static String getName(int move) {
        switch (move) {
            case PEDRA:
                return "PEDRA";
            case PAPEL:
                return "PAPEL";
        }
        return "TESOURA";

    }

}
